package com.kevin.netty.protocol.binary.util;

import com.kevin.netty.protocol.binary.BasicMessage;
import com.kevin.netty.protocol.binary.RequestType;
import com.kevin.netty.protocol.binary.ResponseType;

import java.nio.charset.StandardCharsets;

public class BinaryMessageUtil {

    /**
     * 模拟数据
     */
    public static BasicMessage binaryMock() {
        String payload = "Hello world binary";
        BasicMessage basicMessage = new BasicMessage();
        basicMessage.setHeadSting("$$");
        basicMessage.setRequestType(RequestType.NOTICE);
        basicMessage.setResponseType(ResponseType.SUCCESS);
        basicMessage.setPayload(payload);
        basicMessage.setPayloadLength(payload.length());
        return basicMessage;
    }

    /**
     * 反序列化
     *
     * @param bytes 需要解析的 byte[]
     * @return basicMessage
     */
    public static BasicMessage deserializer(byte[] bytes) {
        BasicMessage basicMessage = new BasicMessage();
        basicMessage.setHeadSting(new String(extract(bytes, 0, 2), StandardCharsets.UTF_8));
        basicMessage.setRequestType(RequestType.valueOf(extract(bytes, 2, 1)[0]));
        basicMessage.setResponseType(ResponseType.valueOf(extract(bytes, 3, 1)[0]));
        basicMessage.setPayloadLength(extract(bytes, 4, 1)[0]);
        basicMessage.setPayload(new String(extract(bytes, 5, basicMessage.getPayloadLength()), StandardCharsets.UTF_8));
        return basicMessage;
    }

    /**
     * 序列化
     *
     * @param basicMessage 基础消息
     * @return byte[]
     */
    public static byte[] serializer(BasicMessage basicMessage) {
        return concat(basicMessage.getHeadSting().getBytes(StandardCharsets.UTF_8),
                new byte[]{basicMessage.getRequestType().getValue()},
                new byte[]{basicMessage.getResponseType().getValue()},
                new byte[]{(byte) basicMessage.getPayload().length()},
                basicMessage.getPayload().getBytes(StandardCharsets.UTF_8));
    }

    /**
     * @param bytes 需要截取的 byte[]
     * @param begin 起始下标位置
     * @param count 截取数据长度
     * @return byte[]
     */
    public static byte[] extract(byte[] bytes, int begin, int count) {
        byte[] bs = new byte[count];
        System.arraycopy(bytes, begin, bs, 0, begin + count - begin);
        return bs;
    }

    /**
     * 合并 byte[]
     *
     * @param arrays 需要合并的 byte[]
     * @return byte[]
     */
    public static byte[] concat(byte[]... arrays) {
        int length = 0;
        int pos = arrays.length;
        for (int var4 = 0; var4 < pos; ++var4) {
            byte[] array = arrays[var4];
            length += array.length;
        }
        byte[] result = new byte[length];
        pos = 0;
        for (byte[] array : arrays) {
            System.arraycopy(array, 0, result, pos, array.length);
            pos += array.length;
        }
        return result;
    }

}
